/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package x10.event;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;

import x10.enums.House;
import x10.enums.Interfaces;

/**
 *
 * @author Denny
 */
public class X10InterfaceStatus extends X10Event implements Serializable {
    static final long serialVersionUID = 1L;
    Interfaces interfaceType = null;
    int firmwareRevision = 0;
    int timeBattery = 0;
    long timeInstantiated = 0L;  //Time instantiated, but can also be used for timehack status was received
    long timeInterface = 0L;
    House monitoredHouseCode = null;
    HashMap<Integer, X10Command> monitoredDevices = new HashMap<Integer, X10Command>();
    private String address;
    private String source;
    private long instantiatedMillis;

    public X10InterfaceStatus(){
	//TODO: fix the constructor on this
        this.instantiatedMillis = System.currentTimeMillis();
        this.address = "STATRESP";
    }

    /**
     * @return the source
     */
    public String getSource() {
        return source;
    }

    /**
     * @param source the source to set
     */
    public void setSource(String source) {
        this.source = source;
    }

    /**
     * @return the address
     */
    public String getAddress() {
        return address;
    }

    /**
     * @param address the address to set
     */
    public void setAddress(String address) {
        this.address = address;
    }

    /**
     * @return the instantiatedMillis
     */
    public long getInstantiatedMillis() {
        return instantiatedMillis;
    }

    /**
     * @param instantiatedMillis the instantiatedMillis to set
     */
    public void setInstantiatedMillis(long instantiatedMillis) {
        this.instantiatedMillis = instantiatedMillis;
    }

    public HashMap<Integer, X10Command> getMonitoredDevices() {
        return monitoredDevices;
    }

    public void setMonitoredDevices(HashMap<Integer, X10Command> monitoredDevices) {
        this.monitoredDevices = monitoredDevices;
    }

    public boolean hasMonitoredDevice(Integer deviceNumber){
        if(monitoredDevices.containsKey(deviceNumber)){
            return true;
        } else {
            return false;
        }
    }

    public X10Command getMonitoredDevice(Integer deviceNumber){
        return monitoredDevices.get(deviceNumber);
    }

    public void setMonitoredDevice(X10Command cmd){
        Integer deviceNumber = cmd.getDeviceCode().ordinal()-1;
        monitoredDevices.put(deviceNumber, cmd);
    }

    public Interfaces getInterfaceType() {
        return interfaceType;
    }

    public void setInterfaceType(Interfaces interfaceType) {
        this.interfaceType = interfaceType;
    }

    public int getTimeBattery() {
        return timeBattery;
    }

    public void setTimeBattery(int timeBattery) {
        this.timeBattery = timeBattery;
    }

    public int getFirmwareRevision() {
        return firmwareRevision;
    }

    public void setFirmwareRevision(int firmwareRevision) {
        this.firmwareRevision = firmwareRevision;
    }

    public long getTimeInterface() {
        return timeInterface;
    }

    public void setTimeInterface(long timeInterface) {
        this.timeInterface = timeInterface;
    }


    public House getMonitoredHouseCode() {
        return monitoredHouseCode;
    }

    public void setMonitoredHouseCode(House monitoredHouseCode) {
        this.monitoredHouseCode = monitoredHouseCode;
    }

    public boolean equals(X10Event device){
        boolean isEqual = true;

        if(device instanceof X10InterfaceStatus){
            X10InterfaceStatus other = (X10InterfaceStatus)device;
            if(other!=null){
                //If both objects are within 1 second of each other, call them equal
                long low = this.getInstantiatedMillis() - 1000; //1 second earlier
                long high = this.getInstantiatedMillis() + 1000; //1 second later
                long otherMillis = other.getInstantiatedMillis();

                if(!((otherMillis >= low) && (otherMillis <= high))){
                    isEqual = false;
                }
                if(!this.source.contentEquals(other.getSource())){
                    isEqual = false;
                }
            }
        } else {
            isEqual = false;
        }

        return isEqual;
    }

    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();

        sb.append(interfaceType);
        sb.append(" INTERFACE STATUS\n");

        sb.append("Software Revision Level: ");
        sb.append(firmwareRevision);
        sb.append("\n");

        Date dateTime = new Date();
        dateTime.setTime(timeInterface);
        sb.append("Interface Time: ");
        sb.append(dateTime.toString());
        sb.append("\n");

        sb.append("Battery Time (secs): ");
        sb.append(timeBattery);
        sb.append("\n");

        sb.append("Monitored House Code: ");
        if(monitoredHouseCode != null){
            sb.append(monitoredHouseCode.toString());
        } else {
            sb.append("Unknown");
        }
        sb.append("\n");

        //Iterate the monitored Devices
        X10Command cmd = null;
        for(int x = 0; x < 16; x++){
            if(hasMonitoredDevice(x)){
                cmd = getMonitoredDevice(x);
                sb.append("Device: ");
                sb.append(cmd.getAddress());
                sb.append(" Status: ");
                sb.append(cmd.getFunctionCode().toString());
                if(cmd.getDimBrightLevel()>0){
                    sb.append(" Dimmed: Yes");
                } else {
                    sb.append(" Dimmed: No");
                }
                sb.append("\n");
            } else {
                sb.append("Device: ");
                if(monitoredHouseCode != null){
                    sb.append(monitoredHouseCode.toString());
                } else {
                    sb.append("x");
                }
                sb.append(x + 1);
                sb.append(" Not Monitored\n");
            }
        }

        return sb.toString();
    }
}
